/**
 * @author Fayçal INAJJARANE
 */
package com.appspot.finajjarane.framework.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.appspot.finajjarane.framework.dao.IArticleDao;
import com.appspot.finajjarane.framework.entities.Article;
import com.appspot.finajjarane.framework.generic.ApplicationConstants;
import com.appspot.finajjarane.framework.generic.Utils;
import com.appspot.finajjarane.framework.models.ArticleModel;
import com.appspot.finajjarane.framework.service.IArticleService;
import com.google.appengine.api.datastore.Category;
import com.google.appengine.api.datastore.Text;

@Service
public class ArticleServiceImpl implements IArticleService {

	@Autowired
	IArticleDao articleDao;

	@Override
	public boolean articleCreateNew(ArticleModel articleModel) throws Exception {

		Article article = ArticleModelToArticle(articleModel);
		return articleDao.add(article);

	}

	@Override
	public boolean articleUpdate(ArticleModel articleModel) throws Exception {
		Article article = ArticleModelToArticle(articleModel);
		try {
			articleDao.merge(article);
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	@Override
	public boolean articleRemove(Long articleId) throws Exception {
		return this.articleDao.removeByKey(articleId);
	}

	@Override
	public List<ArticleModel> getArticlesList(final int page, final int maxPerPage, final String lang)  throws Exception{

		List<ArticleModel> articlesToReturn = new ArrayList<ArticleModel>();
		List<Article> articles = this.articleDao.getLimitedList(page, maxPerPage, lang, "publishedDate", "DESC");

		if(null==articles){
			return articlesToReturn;
		}

		for(Article article : articles){
			String articleBody = article.getBody().getValue();
			if(articleBody.length()>100){
				article.setBody(new Text(articleBody.substring(0, ApplicationConstants.NBR_CHARS_SHORT_ARTICLE) + "..."));
			}
			articlesToReturn.add(ArticleToArticleModel(article));
		}
		return articlesToReturn;
	}

	@Override
	public ArticleModel getArticle(Long id)  throws Exception{

		Article article = this.articleDao.findByKey(id);
		return ArticleToArticleModel(article);

	}

	@Override
	public List<ArticleModel> getArticlesAll()  throws Exception{
		List<Article> articles = this.articleDao.findAll();
		List<ArticleModel> articleModels = new ArrayList<ArticleModel>();

		for(Article article : articles){
			articleModels.add(ArticleToArticleModel(article));
		}

		return articleModels;
	}



	//###################### UTILITY METHODS #######################

	/**
	 * Utility method to convert Article to ArticleModel
	 * @param article
	 * @return ArticleModel
	 */
	private ArticleModel ArticleToArticleModel(Article article){

		ArticleModel articleModel = new ArticleModel();
		List<String> tagsModels = new ArrayList<String>();

		for(Category tag : article.getTags()){
			tagsModels.add(tag.getCategory());
		}

		articleModel.setId(article.getId());
		articleModel.setTitle(article.getTitle());
		articleModel.setBody(article.getBody().getValue());
		articleModel.setTags(tagsModels);
		articleModel.setLang(article.getLang());
		articleModel.setImageSmall(article.getImageSmall());
		articleModel.setImageCarousel(article.getImageCarousel());
		articleModel.setPublishedDate(Utils.dateToDateDetailsModel(article.getPublishedDate(),article.getLang()));

		return articleModel;

	}


	/**
	 * Utility method to convert ArticleModel to Article
	 * @param articleModel
	 * @return Article
	 */
	private Article ArticleModelToArticle(ArticleModel articleModel){

		Article article = new Article();
		List<Category> tags = new ArrayList<Category>();


		for(String tagModel : articleModel.getTags()){
			if(null==tagModel || tagModel.isEmpty()){
				continue;
			}
			tags.add(new Category(tagModel));
		}

		article.setId(articleModel.getId());
		article.setTitle(articleModel.getTitle());
		article.setTags(tags);
		article.setBody(new Text(articleModel.getBody()));
		article.setLang(articleModel.getLang());
		article.setPublishedDate(new Date());
		article.setImageSmall(articleModel.getImageSmall());
		article.setImageCarousel(articleModel.getImageCarousel());


		return article;

	}

	@Override
	public int getArticlesCount(final String lang)  throws Exception{
		return this.articleDao.getEntriesCount("id",lang);
	}

}